--[[
	CREDITS:
	LynStats for all the basecode
	Cargor (EU-Nozdormu) for making memorytag with Tooltip when Lynstats didn't had it, and guildTag
--]]
-- Lets make our frames
local addon = CreateFrame("Button", nil, UIParent)
local frame2 = CreateFrame("Button", nil, UIParent) 
local frame3 = CreateFrame("Button", nil, UIParent) 
local frame4 = CreateFrame("Button", nil , UIParent)

-- configuration for all frames
local size = 12
local font = "Interface\\AddOns\\lolStats\\Fonts\\accid___.ttf"

local guild_text, guild, ticktack, lag, fps, ep, xp_cur, xp_max, text, f2_text, f3_text, memory, mem, entry, i

local colors = {
	DRUID   = "ff7c0a",
	HUNTER  = "abd473",
	MAGE    = "68ccef",
	PALADIN = "f48cba",
	PRIEST  = "ffffff",
	ROGUE   = "fff468",
	SHAMAN  = "00dbba",
	WARLOCK = "9382c9",
	WARRIOR = "c69b6d"
}

local itemSlots = { "Head", "Shoulder", "Chest", "Waist", "Legs", "Feet", "Wrist", "Hands", "MainHand", "SecondaryHand", "Ranged" }
local function ColorGradient(perc, ...)
	if perc >= 1 then
		local r, g, b = select(select('#', ...) - 2, ...)
		return r, g, b
	elseif perc <= 0 then
		local r, g, b = ...
		return r, g, b
	end
	
	local num = select('#', ...) / 3

	local segment, relperc = math.modf(perc*(num-1))
	local r1, g1, b1, r2, g2, b2 = select((segment*3)+1, ...)

	return r1 + (r2-r1)*relperc, g1 + (g2-g1)*relperc, b1 + (b2-b1)*relperc
end


local memformat = function(number)
	if number > 1000 then
		return string.format("%.2f mb", number / 1000)
	else
		return string.format("%.1f kb", number)
	end
end

local addoncompare = function(a, b)
	return a.memory > b.memory
end

-- Set frame1
function addon:new()
	self:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -50, 3)
	self:SetWidth(120)
	self:SetHeight(12)
	
	text = self:CreateFontString(nil, "OVERLAY")
	text:SetFont(font, size, nil)
	text:SetShadowOffset(1,-1)
	text:SetPoint("TOPLEFT", self)
	
	self:SetScript("OnUpdate", self.update)
	self:SetScript("OnClick", self.onClick)
	self:SetScript("OnEnter", self.enter)
	self:SetScript("OnLeave", function() GameTooltip:Hide() end)
end

-- Here comes the second frame 
function frame2:new()
	self:SetPoint("BOTTOMLEFT", frame4, "BOTTOMLEFT", 35, 0)
	self:SetWidth(15)
	self:SetHeight(20)
	
	f2_text = self:CreateFontString(nil, "OVERLAY")
	f2_text:SetFont(font, size, nil)
	f2_text:SetShadowOffset(1,-1)
	f2_text:SetPoint("BOTTOMLEFT", self)
	
	self:SetScript("OnUpdate", self.update)
end

--Here comes the third frame
function frame3:new()
	self:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", 5, 3)
	self:SetWidth(15)
	self:SetHeight(20)
	
	f3_text = self:CreateFontString(nil, "OVERLAY")
	f3_text:SetFont(font, size, nil)
	f3_text:SetShadowOffset(1,-1)
	f3_text:SetPoint("BOTTOMLEFT", self)
	
	self:SetScript("OnUpdate", self.update)
end

-- Creation of Guildframe
function frame4:new()
	self:SetPoint("BOTTOMRIGHT", frame3, "BOTTOMRIGHT", 70, 0)
	self:SetWidth(30)
	self:SetHeight(12)

	guild_text = self:CreateFontString(nil, "OVERLAY")
	guild_text:SetFont(font, size, nil)
	guild_text:SetShadowOffset(1,-1)
	guild_text:SetPoint("BOTTOMLEFT", self)

    self:RegisterEvent("GUILD_ROSTER_UPDATE")
	self:RegisterEvent("PLAYER_GUILD_UPDATE")
	self:RegisterEvent("GUILD_MOTD")
    self:RegisterEvent("PLAYER_ENTERING_WORLD")
	self:SetScript("OnEvent", self.event)
	self:SetScript("OnUpdate", self.update)
end

local last = 0
function addon:update(elapsed)
	last = last + elapsed

	if last > 1 then
		fps = GetFramerate()
		fps = "|c00ffffff"..floor(fps).."|r|cFF4E95FFfps|r      "
		
		lag = select(3, GetNetStats())
		lag = "|c00ffffff"..lag.."|r|cFF4E95FFms|r      "
		
		mem = string.format("%.1f" ,collectgarbage("count")/1024)  
	    mem = "|c00ffffff"..mem.."|r|cFF4E95FFmb|r      " 
		
	-- Durability stuff
	local min = 1
	for _, slot in pairs(itemSlots) do
		local durability, maximum, percent = nil
		local id = GetInventorySlotInfo(slot.."Slot")
		durability, maximum = GetInventoryItemDurability(id)
		if durability then
			if maximum ~= 0 then
				percent = durability/maximum
			else percent = 1
			end
			if percent < min then
				min = percent
			end
		end
	end
		
	local r, g, b = ColorGradient(min, 1,0,0, 1,1,0, 0,1,0)
	dur = "|c00"..string.format("%02x%02x%02x%.0f",r*255,g*255,b*255,min*100).."%|r"
		
	last = 0
		
	text:SetText(fps..lag..mem..dur)
	end
end

-- and the update-function of course for the 2 other frames ;)
local f2_last = 0
function frame2:update(f2_elapsed)
	f2_last = f2_last + f2_elapsed

	-- xp stuff
	xp_cur = UnitXP("player")
		xp_max = UnitXPMax("player")
		if UnitLevel("player") < MAX_PLAYER_LEVEL then
			ep = "|c00ffffff"..floor(xp_max - xp_cur).."|r|cFF4E95FFxp|r"
		else
			ep = ""
		end
	
	if f2_last > 1 then
		f2_last = 0
		f2_text:SetText(ep)
	end
end

local f3_last = 0
function frame3:update(f3_elapsed)
	f3_last = f3_last + f3_elapsed

	-- date thingy
	ticktack = date("%H:%M:%S")
	ticktack = "|c00ffffff"..ticktack.."|r"
	
	if f3_last > 1 then
		f3_last = 0
		f3_text:SetText(ticktack)
	end
end
-- MouseoverTooltip with memoryList
function addon:enter()  
	GameTooltip:SetOwner(self, "ANCHOR_BOTTOMRIGHT")  
  
    addons = {}  
    total = 0  
  
    UpdateAddOnMemoryUsage()  
  
    for i=1, GetNumAddOns(), 1 do  
		if (GetAddOnMemoryUsage(i) > 0 ) then
        memory = GetAddOnMemoryUsage(i)  
        entry = {name = GetAddOnInfo(i), memory = memory}  
        table.insert(addons, entry)  
        total = total + memory  
		end
    end  
  
    table.sort(addons, addoncompare)  
  
    i = 0  
    for _, entry in pairs(addons) do  
			if entry.memory > 200 then
                GameTooltip:AddDoubleLine(entry.name, memformat(entry.memory), 1, 1, 1, 1, 0.1, 0.1, 1)
			elseif entry.memory > 120 then
                GameTooltip:AddDoubleLine(entry.name, memformat(entry.memory), 1, 1, 1, 1, 0.5, 0.1, 1)
            elseif entry.memory > 80 then
                GameTooltip:AddDoubleLine(entry.name, memformat(entry.memory), 1, 1, 1, 0.85, 0.85, 0, 1)
            else
                GameTooltip:AddDoubleLine(entry.name, memformat(entry.memory), 1, 1, 1, 73/255, 226/255, 14/255, 1)
            end
        i = i + 1  
        if i >= 50 then  
            break  
        end  
    end  
  
    GameTooltip:AddLine("\n")  
    GameTooltip:AddDoubleLine("Total", memformat(total), 1, 1, 0, 1, 1, 0)  
    GameTooltip:Show()  
end

function addon:onClick()
   collectgarbage()
    DEFAULT_CHAT_FRAME:AddMessage("Garbage Collected.")
end
	
-- Data for Guildframe
function frame4:event()
local text, guildonline, guildtotal

local function getclasscolor(class)
	class = strupper(class)
	return format("%02x%02x%02x", _G["RAID_CLASS_COLORS"][class].r*255, _G["RAID_CLASS_COLORS"][class].g*255, _G["RAID_CLASS_COLORS"][class].b*255)
end
local function getdiffcolor(lvl)
local dfcolor = GetDifficultyColor(lvl)
	if not dfcolor then 
		return "ffffff" 
	end
	return format("%02x%02x%02x", dfcolor.r*255, dfcolor.g*255, dfcolor.b*255)
end

-- We need to clear the table data to give a fresh update
guild = nil
guildonline = 0
-- Ok, we need the total number of guild members on the roster first
if IsInGuild() then
	guildtotal = GetNumGuildMembers(true)
    -- Now let's get our count of how many guild are online
    for i = 0, guildtotal do
        name, rank, rankIndex, level, class, zone, note, officernote, online, status = GetGuildRosterInfo(i);
        if online and name then
            -- If they're online, we'll add them to our guild table
			guildonline = guildonline + 1
            if not guild then guild = {} end
			local classcolor = getclasscolor(string.format("%s", class))
            local coloredname = string.format("|cff%s%s%s|r", classcolor, status, name)
			local coloredlvl = string.format("|cff%s%s|r", getdiffcolor(level), level)
            table.insert(guild, { coloredname, coloredlvl, zone })
        end
    end
		
-- Setting up button text
    text = string.format("%s/%s", guildonline, guildtotal)
    -- Now update module text with our new text
end
guild_text:SetText(text)
    
-- Let's setup our tooltip
if IsInGuild() then
    self:EnableMouse(true)
    self:SetScript("OnEnter", function(this)
		GameTooltip:SetOwner(this, "ANCHOR_TOPLEFT")
		GameTooltip:AddLine(string.format("%s/%s %s", guildonline, guildtotal, "Members Online"))
		GameTooltip:AddLine("-------------------------", 1, 1, 1)
		GameTooltip:AddLine(GetGuildRosterMOTD(), 1, 1, 1)
		GameTooltip:AddLine(" ", 1, 1, 1)
		for _, val in ipairs(guild) do
			local ptext = string.format("%s", val[1])
			local dtext = string.format("%s %s", val[3] , val[2])
			GameTooltip:AddDoubleLine(ptext, dtext, 1, 1, 1, 1, 1, 1)
		end
		GameTooltip:Show()
    end)
	self:SetScript("OnLeave", function()
        if GameTooltip:IsShown() then
            GameTooltip:Hide()
        end
	end)
else
	self:SetScript("OnEnter", nil)
	self:SetScript("OnLeave", nil)
	end
end
-- Update roster information every 15 sec
local last = 0
function frame4:update(elapsed)
last = last + elapsed
	if last > 15 then
		last = 0
		GuildRoster()
	end
end

-- activate our shit
addon:new()
frame2:new() 
frame3:new()
frame4:new()